package com.zluyuer.ermu.msg;

import java.util.UUID;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

public abstract class Message {
    
    private String id;
    private String code;
    private Document xmldoc;
    
    public Message() {
        create(getMsgCode());
    }
    
    public Message(String code) {
        create(code);
    }
    
    public int length() throws Exception {
        return toXML().length();
    }
    
    private void create(String code) {
        this.code = code;
        this.id = UUID.randomUUID().toString();
        this.xmldoc = DocumentHelper.createDocument();
        
        Element root = xmldoc.addElement("root");
        root.addElement("head");
        root.addElement("body");
    }
    
    public String getMsgCode() {
        return getClass().getSimpleName();
    }

    private void build() throws Exception {
        Element root = xmldoc.getRootElement();
        root.element("head").clearContent();
        buildHead(root.element("head"));
        root.element("body").clearContent();
        buildBody(root.element("body"));
    }
    
    private void buildHead(Element head) {
        head.addElement("id").setText(id);
        head.addElement("code").setText(code);
    }
    
    public abstract void buildBody(Element body)  throws Exception;
    
    public String toXML() throws Exception {
        build();
        return xmldoc.asXML();
    }
    
    public void parse(Document doc) throws Exception {
        Element root = doc.getRootElement();
        parseHead(root.element("head"));
        parseBody(root.element("body"));
    }
    
    private void parseHead(Element head) {
        id = head.elementText("id");
        code = head.elementText("code");
    }
    
    protected abstract void parseBody(Element body) throws Exception;
    
    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }
    
}
